package com.ayf.payment.game.api.excel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.swwx.charm.commons.lang.utils.LogPortal;
import com.ayf.payment.game.api.entity.MerchantBatchPayFile;
import com.ayf.payment.game.api.entity.MerchantBatchPayFileFailReason;
import com.ayf.payment.game.api.entity.MerchantPayOrder;
import com.ayf.payment.game.api.exception.ParameterException;
import com.ayf.payment.game.api.service.MerchantPayOrderService;
import com.ayf.payment.game.api.utils.DateUtils;
import com.ayf.payment.game.api.utils.SnowFlakeUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Description: excel数据导入
 * @Author: zh-liang
 * @Date : 2020-04-17 15:51
 */
public class UploadPayOrderListener extends AnalysisEventListener<UploadPayOrderData> {

    private static final int BATCH_COUNT = 500;

    List<UploadPayOrderData> list = new ArrayList<>();

    private List<MerchantPayOrder> successList = new ArrayList<>();
    private List<MerchantBatchPayFileFailReason> failList = new ArrayList<>();
    private BigDecimal sum;

    private MerchantPayOrderService merchantPayOrderService;

    private Integer merchantId;

    private String traceId;

    private String fileName;

    /**
     * 每次创建Listener的时候需要把spring管理的类传进来
     *
     * @param traceId
     * @param merchantId
     * @param fileName
     * @param merchantPayOrderService
     */
    public UploadPayOrderListener(String traceId, Integer merchantId, String fileName, MerchantPayOrderService merchantPayOrderService) {
        this.merchantPayOrderService = merchantPayOrderService;
        this.merchantId = merchantId;
        this.traceId = traceId;
        this.fileName = fileName;
    }

    /**
     * 这个每一条数据解析都会来调用
     *
     * @param payOrderData
     * @param context
     */
    @Override
    public void invoke(UploadPayOrderData payOrderData, AnalysisContext context) {
        LogPortal.info("[{}]批量代付导入-解析到一条数据:[{}]", traceId, JSON.toJSONString(payOrderData));
        list.add(payOrderData);
        if (list.size() > BATCH_COUNT) {
            throw new ParameterException("批量代付导入失败，最大仅支持" + BATCH_COUNT + "条数据导入");
        }
    }

    /**
     * 所有数据解析完成了 才会来调用
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        if (list.size() == 0) {
            throw new ParameterException("Excel数据为空");
        }

        //保存上传文件信息
        MerchantBatchPayFile batchPayFile=new MerchantBatchPayFile();
        String batchPayFileId = SnowFlakeUtils.getUniqueId();
        batchPayFile.setId(batchPayFileId);
        batchPayFile.setMerchantId(merchantId);
        batchPayFile.setStatus(0);
        String concat = DateUtils.dateToString(DateUtils.getNowDate(), "yyMMdd").concat(SnowFlakeUtils.getUniqueId());
        String bathNo = "PC".concat(concat);
        batchPayFile.setBatchNo(bathNo);
        batchPayFile.setCreateTimeIndex(DateUtils.dateToInteger(new Date()));
        batchPayFile.setFileName(fileName);
        merchantPayOrderService.add(batchPayFile);

        //数据校检
        checkData(batchPayFileId);

        //数据结果保存
        MerchantBatchPayFile merchantBatchPayFile=new MerchantBatchPayFile();
        merchantBatchPayFile.setId(batchPayFileId);
        merchantBatchPayFile.setMerchantId(merchantId);
        merchantBatchPayFile.setBatchNo(bathNo);
        merchantBatchPayFile.setTotalAmt(sum);
        merchantBatchPayFile.setTotalCount(list.size());
        merchantPayOrderService.bathAddPay(bathNo,successList,failList,merchantBatchPayFile);
        LogPortal.info("[{}]批量代付导入-所有数据解析完成！", traceId);
    }

    /**
     * 校检数据
     *
     * @return
     */
    private void checkData(String batchPayFileId) {
        LogPortal.info("[{}]批量代付导入-本次校检[{}]条数据，开始校检数据！", traceId, list.size());
        CheckUploadPayOrderDTO dto = merchantPayOrderService.checkData(merchantId, batchPayFileId, list);
        if (dto.getFailList() != null && dto.getFailList().size() > 0) {
            failList.addAll(dto.getFailList());
        }
        if (dto.getSuccessList() != null && dto.getSuccessList().size() > 0) {
            successList.addAll(dto.getSuccessList());
        }
        if (dto.getSum() != null) {
            sum = dto.getSum();
        }
        LogPortal.info("[{}]批量代付导入-本次校检[{}]条完成", traceId, list.size());
    }
}
